﻿using Castle.DynamicProxy;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;

namespace Luka;

/// <summary>
/// 缓存Aop
/// </summary>
public class CacheAop : IInterceptor
{
    /// <summary>
    /// 内存缓存
    /// </summary>
    private static readonly MemoryCache _cache = new(new MemoryCacheOptions());

    /// <summary>
    /// 重写方法
    /// </summary>
    public void Intercept(IInvocation invocation)
    {
        var method = invocation.MethodInvocationTarget ?? invocation.Method;
        var cachingAttribute = method.GetAttribute<CachingAttribute>();
        if (cachingAttribute != null)
        {
            //方法名作为key
            var key = $"{CacheConst.Cache_Result}{invocation.Method.Name}";
            object response;
            //执行方法
            invocation.Proceed();
            //获取值
            if (invocation.Method.IsAsyncMethod())
            {
                dynamic result = invocation.ReturnValue;
                response = result.Result;
            }
            else
            {
                response = invocation.ReturnValue;
            }
            //默认值
            response ??= string.Empty;
            //缓存
            var distributedCache = InternalApp.GetService<ICacheHandler>();
            if (distributedCache != null && !distributedCache.Exists(key))
            {
                distributedCache.Set(key, response, cachingAttribute.Minute);
            }
            else if (!_cache.TryGetValue(key, out _))
            {
                _cache.Set(key, response, TimeSpan.FromMinutes(cachingAttribute.Minute));
            }
        }
        else
        {
            invocation.Proceed();
        }
    }
}